#ifndef HwFederateAmbassador_h
#define HwFederateAmbassador_h

#if defined(_MSC_VER)
#define RTI_USES_STD_FSTREAM
#endif // defined(_MSC_VER)
#include <RTI.hh>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <string>
#include <cstring>
#include <arpa/inet.h>
#include <chrono>
#include <thread>

#include "json.hpp"
#include "easylogging++.h"

//-----------------------------------------------------------------
//                RTI 1.3 Parameter Passing Memory Conventions
//
// C1  In parameter by value.
// C2  Out parameter by reference.
// C3  Function return by value.
// C4  In parameter by const reference.  Caller provides memory.
//     Caller may free memory or overwrite it upon completion of
//     the call.  Callee must copy during the call anything it
//     wishes to save beyond completion of the call.  Parameter
//     type must define const accessor methods.
// C5  Out parameter by reference.  Caller provides reference to object.
//     Callee constructs an instance on the heap (new) and returns.
//     The caller destroys the instance (delete) at its leisure.
// C6  Function return by reference.  Callee constructs an instance on
//     the heap (new) and returns a reference.  The caller destroys the
//     instance (delete) at its leisure.
//-----------------------------------------------------------------

//-----------------------------------------------------------------
//
// CLASS:
//     HwFederateAmbassador
//
// PURPOSE:
//     Derived class of abstract FederateAmbassador class to
//     implement methods so that RTI can call functions in
//     the federate.
//
// HISTORY:
//     1) Created 11/6/96
//     2) Updated to RTI 1.3 3/26/98
//
//-----------------------------------------------------------------
class HwFederateAmbassador : public RTI::FederateAmbassador
{
public:
    HwFederateAmbassador();
    virtual ~HwFederateAmbassador() throw(RTI::FederateInternalError);

    ////////////////////////////////////
    // Federation Management Services //
    ////////////////////////////////////

    virtual void synchronizationPointRegistrationSucceeded(
        const char *label) // supplied C4)
        throw(
            RTI::FederateInternalError);

    virtual void synchronizationPointRegistrationFailed(
        const char *label) // supplied C4)
        throw(
            RTI::FederateInternalError);

    virtual void announceSynchronizationPoint(
        const char *label, // supplied C4
        const char *tag)   // supplied C4
        throw(
            RTI::FederateInternalError);

    virtual void federationSynchronized(
        const char *label) // supplied C4)
        throw(
            RTI::FederateInternalError);

    virtual void initiateFederateSave(
        const char *label) // supplied C4
        throw(
            RTI::UnableToPerformSave,
            RTI::FederateInternalError);

    virtual void federationSaved() throw(
        RTI::FederateInternalError);

    virtual void federationNotSaved() throw(
        RTI::FederateInternalError);

    virtual void requestFederationRestoreSucceeded(
        const char *label) // supplied C4
        throw(
            RTI::FederateInternalError);

    virtual void requestFederationRestoreFailed(
        const char *label) // supplied C4
        throw(
            RTI::FederateInternalError);

    virtual void requestFederationRestoreFailed(
        const char *label,
        const char *reason) // supplied C4
        throw(
            RTI::FederateInternalError);

    virtual void federationRestoreBegun() throw(
        RTI::FederateInternalError);

    virtual void initiateFederateRestore(
        const char *label,          // supplied C4
        RTI::FederateHandle handle) // supplied C1
        throw(
            RTI::SpecifiedSaveLabelDoesNotExist,
            RTI::CouldNotRestore,
            RTI::FederateInternalError);

    virtual void federationRestored() throw(
        RTI::FederateInternalError);

    virtual void federationNotRestored() throw(
        RTI::FederateInternalError);

    /////////////////////////////////////
    // Declaration Management Services //
    /////////////////////////////////////

    virtual void startRegistrationForObjectClass(
        RTI::ObjectClassHandle theClass) // supplied C1
        throw(
            RTI::ObjectClassNotPublished,
            RTI::FederateInternalError);

    virtual void stopRegistrationForObjectClass(
        RTI::ObjectClassHandle theClass) // supplied C1
        throw(
            RTI::ObjectClassNotPublished,
            RTI::FederateInternalError);

    virtual void turnInteractionsOn(
        RTI::InteractionClassHandle theHandle) // supplied C1
        throw(
            RTI::InteractionClassNotPublished,
            RTI::FederateInternalError);

    virtual void turnInteractionsOff(
        RTI::InteractionClassHandle theHandle) // supplied C1
        throw(
            RTI::InteractionClassNotPublished,
            RTI::FederateInternalError);

    ////////////////////////////////
    // Object Management Services //
    ////////////////////////////////

    virtual void discoverObjectInstance(
        RTI::ObjectHandle theObject,           // supplied C1
        RTI::ObjectClassHandle theObjectClass, // supplied C1
        const char *theObjectName)             // supplied C4
        throw(
            RTI::CouldNotDiscover,
            RTI::ObjectClassNotKnown,
            RTI::FederateInternalError);

    virtual void reflectAttributeValues(
        RTI::ObjectHandle theObject,                           // supplied C1
        const RTI::AttributeHandleValuePairSet &theAttributes, // supplied C4
        const RTI::FedTime &theTime,                           // supplied C1
        const char *theTag,                                    // supplied C4
        RTI::EventRetractionHandle theHandle)                  // supplied C1
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::FederateOwnsAttributes,
            RTI::InvalidFederationTime,
            RTI::FederateInternalError);

    virtual void reflectAttributeValues(
        RTI::ObjectHandle theObject,                           // supplied C1
        const RTI::AttributeHandleValuePairSet &theAttributes, // supplied C4
        const char *theTag)                                    // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::FederateOwnsAttributes,
            RTI::FederateInternalError);

    // 4.6
    virtual void receiveInteraction(
        RTI::InteractionClassHandle theInteraction,            // supplied C1
        const RTI::ParameterHandleValuePairSet &theParameters, // supplied C4
        const RTI::FedTime &theTime,                           // supplied C4
        const char *theTag,                                    // supplied C4
        RTI::EventRetractionHandle theHandle)                  // supplied C1
        throw(
            RTI::InteractionClassNotKnown,
            RTI::InteractionParameterNotKnown,
            RTI::InvalidFederationTime,
            RTI::FederateInternalError);

    virtual void receiveInteraction(
        RTI::InteractionClassHandle theInteraction,            // supplied C1
        const RTI::ParameterHandleValuePairSet &theParameters, // supplied C4
        const char *theTag)                                    // supplied C4
        throw(
            RTI::InteractionClassNotKnown,
            RTI::InteractionParameterNotKnown,
            RTI::FederateInternalError);

    virtual void removeObjectInstance(
        RTI::ObjectHandle theObject,          // supplied C1
        const RTI::FedTime &theTime,          // supplied C4
        const char *theTag,                   // supplied C4
        RTI::EventRetractionHandle theHandle) // supplied C1
        throw(
            RTI::ObjectNotKnown,
            RTI::InvalidFederationTime,
            RTI::FederateInternalError);

    virtual void removeObjectInstance(
        RTI::ObjectHandle theObject, // supplied C1
        const char *theTag)          // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::FederateInternalError);

    virtual void attributesInScope(
        RTI::ObjectHandle theObject,                  // supplied C1
        const RTI::AttributeHandleSet &theAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::FederateInternalError);

    virtual void attributesOutOfScope(
        RTI::ObjectHandle theObject,                  // supplied C1
        const RTI::AttributeHandleSet &theAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::FederateInternalError);

    virtual void provideAttributeValueUpdate(
        RTI::ObjectHandle theObject,                  // supplied C1
        const RTI::AttributeHandleSet &theAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::AttributeNotOwned,
            RTI::FederateInternalError);

    virtual void turnUpdatesOnForObjectInstance(
        RTI::ObjectHandle theObject,                  // supplied C1
        const RTI::AttributeHandleSet &theAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotOwned,
            RTI::FederateInternalError);

    virtual void turnUpdatesOffForObjectInstance(
        RTI::ObjectHandle theObject,                  // supplied C1
        const RTI::AttributeHandleSet &theAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotOwned,
            RTI::FederateInternalError);

    ///////////////////////////////////
    // Ownership Management Services //
    ///////////////////////////////////

    virtual void requestAttributeOwnershipAssumption(
        RTI::ObjectHandle theObject,                      // supplied C1
        const RTI::AttributeHandleSet &offeredAttributes, // supplied C4
        const char *theTag)                               // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::AttributeAlreadyOwned,
            RTI::AttributeNotPublished,
            RTI::FederateInternalError);

    virtual void attributeOwnershipDivestitureNotification(
        RTI::ObjectHandle theObject,                       // supplied C1
        const RTI::AttributeHandleSet &releasedAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::AttributeNotOwned,
            RTI::AttributeDivestitureWasNotRequested,
            RTI::FederateInternalError);

    virtual void attributeOwnershipAcquisitionNotification(
        RTI::ObjectHandle theObject,                      // supplied C1
        const RTI::AttributeHandleSet &securedAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::AttributeAcquisitionWasNotRequested,
            RTI::AttributeAlreadyOwned,
            RTI::AttributeNotPublished,
            RTI::FederateInternalError);

    virtual void attributeOwnershipUnavailable(
        RTI::ObjectHandle theObject,                  // supplied C1
        const RTI::AttributeHandleSet &theAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::AttributeAlreadyOwned,
            RTI::AttributeAcquisitionWasNotRequested,
            RTI::FederateInternalError);

    virtual void requestAttributeOwnershipRelease(
        RTI::ObjectHandle theObject,                        // supplied C1
        const RTI::AttributeHandleSet &candidateAttributes, // supplied C4
        const char *theTag)                                 // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::AttributeNotOwned,
            RTI::FederateInternalError);

    virtual void confirmAttributeOwnershipAcquisitionCancellation(
        RTI::ObjectHandle theObject,                  // supplied C1
        const RTI::AttributeHandleSet &theAttributes) // supplied C4
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::AttributeAlreadyOwned,
            RTI::AttributeAcquisitionWasNotCanceled,
            RTI::FederateInternalError);

    virtual void informAttributeOwnership(
        RTI::ObjectHandle theObject,       // supplied C1
        RTI::AttributeHandle theAttribute, // supplied C1
        RTI::FederateHandle theOwner)      // supplied C1
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::FederateInternalError);

    virtual void attributeIsNotOwned(
        RTI::ObjectHandle theObject,       // supplied C1
        RTI::AttributeHandle theAttribute) // supplied C1
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::FederateInternalError);

    virtual void attributeOwnedByRTI(
        RTI::ObjectHandle theObject,       // supplied C1
        RTI::AttributeHandle theAttribute) // supplied C1
        throw(
            RTI::ObjectNotKnown,
            RTI::AttributeNotKnown,
            RTI::FederateInternalError);

    //////////////////////////////
    // Time Management Services //
    //////////////////////////////

    virtual void timeRegulationEnabled(
        const RTI::FedTime &theFederateTime) // supplied C4
        throw(
            RTI::InvalidFederationTime,
            RTI::EnableTimeRegulationWasNotPending,
            RTI::FederateInternalError);

    virtual void timeConstrainedEnabled(
        const RTI::FedTime &theFederateTime) // supplied C4
        throw(
            RTI::InvalidFederationTime,
            RTI::EnableTimeConstrainedWasNotPending,
            RTI::FederateInternalError);

    virtual void timeAdvanceGrant(
        const RTI::FedTime &theTime) // supplied C4
        throw(
            RTI::InvalidFederationTime,
            RTI::TimeAdvanceWasNotInProgress,
            RTI::FederateInternalError);

    virtual void requestRetraction(
        RTI::EventRetractionHandle theHandle) // supplied C1
        throw(
            RTI::EventNotKnown,
            RTI::FederateInternalError);

    /////-----自定义-----

    // 定义tcp套接字listener文件描述符
    int listener;

    // 定义接受accepter文件描述符
    int accepter;
    // 连接服务器本地的IP port
    struct sockaddr_in addr;

    // 要发送的同步信息和车辆数量信息
    std::vector<std::string> sendSyncInfoParams;
    // 要发送的车辆参数名列表
    std::vector<std::string> sendCarParams;

    // 需要发送的所有车辆数据 json数组
    nlohmann::ordered_json allCarDataArray = nlohmann::json::array();


    // Test参数
    int port = 9999;
    int sentCount = 0;
    int needSendCount = -1;
};

#endif
